package cn.tedu.anjiadb.service.impl;

import cn.tedu.anjiadb.ex.ServiceException;
import cn.tedu.anjiadb.mapper.UserMapper;
import cn.tedu.anjiadb.pojo.dto.UserAddNewDTO;
import cn.tedu.anjiadb.pojo.dto.UserLoginInfoDTO;
import cn.tedu.anjiadb.pojo.dto.UserUpdateDTO;
import cn.tedu.anjiadb.pojo.entity.User;
import cn.tedu.anjiadb.pojo.vo.ProductListItemVO;
import cn.tedu.anjiadb.pojo.vo.UserStandardVO;
import cn.tedu.anjiadb.security.UsersDetails;
import cn.tedu.anjiadb.service.IUserService;
import cn.tedu.anjiadb.web.ServiceCode;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Slf4j
@Service
public class UserServiceImpl implements IUserService{
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private AuthenticationManager authenticationManager;

    @Override
    public String login(UserLoginInfoDTO userLoginInfoDTO) {
        log.debug("开始处理【用户登录】的业务，参数：{}", userLoginInfoDTO);

        Authentication authentication = new UsernamePasswordAuthenticationToken(
                userLoginInfoDTO.getUsername(),userLoginInfoDTO.getPassword());
        Authentication authenticationResult
                = authenticationManager.authenticate(authentication);
        log.debug("验证登录成功，返回的Authentication为：{}", authenticationResult);
//        SecurityContext securityContext = SecurityContextHolder.getContext();
//        securityContext.setAuthentication(authentication);
        Object principal = authenticationResult.getPrincipal();
        log.debug("获取验证登录成功后的结果中的当事人：{}", principal);
        UsersDetails usersDetails = (UsersDetails) principal;
        Map<String,Object> claims = new HashMap<>();
        claims.put("id",usersDetails.getId());
        claims.put("username",usersDetails.getUsername());
        log.debug("即将生成JWT数据，包含的账号信息：{}", claims);

        String secretKey = "kU4jrFA3iuI5jn25u743kfDs7a8pFEwS54hm";
        Date exp = new Date(System.currentTimeMillis() + 10 * 24 * 60 * 60 * 1000);
        String jwt = Jwts.builder()
                .setHeaderParam("alg", "HS256")
                .setHeaderParam("typ", "JWT")
                .setClaims(claims)
                .setExpiration(exp)
                .signWith(SignatureAlgorithm.HS256, secretKey)
                .compact();
        log.debug("生成了JWT数据，并将返回此JWT数据：{}", jwt);
        return jwt;
    }

    @Override
    public void addNew(UserAddNewDTO userAddNewDTO){
        String name = userAddNewDTO.getUsername();
        int countByName = userMapper.countByName(name);
        if (countByName > 0){
            String message = "注册用户失败，用户名已被占用！";
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }

        String nickName = userAddNewDTO.getNickname();
        int countByNickName = userMapper.countByNickName(nickName);
        if (countByNickName > 0){
            String message = "注册用户失败，昵称已被占用！";
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }

        Long phoneNum = userAddNewDTO.getPhoneNum();
        int countByPhoneNum = userMapper.countByPhoneNum(phoneNum);
        if (countByPhoneNum > 0){
            String message = "注册用户失败，该用户手机号已被注册！";
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }

        User user = new User();
        BeanUtils.copyProperties(userAddNewDTO,user);

        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String rawPassword = user.getPassword();
        String encodedPassword = passwordEncoder.encode(rawPassword);
        user.setPassword(encodedPassword);
        int rows = userMapper.insert(user);
        if (rows != 1){
            String message = "注册用户失败，服务器忙，请稍后再尝试！";
            throw new ServiceException(ServiceCode.ERR_UNKNOWN,message);
        }

    }

    @Override
    public UserStandardVO getStandardById(Long id){
        UserStandardVO userStandardVO = userMapper.getStandardById(id);
        return userStandardVO;
    }

    @Override
    public void deleteById(Long id) {
        UserStandardVO queryResult = userMapper.getStandardById(id);
        if (queryResult == null) {
            String message = "注销用户失败，该用户不存在！";
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        int rows = userMapper.deleteById(id);
        if (rows != 1){
            String message = "注销用户失败，服务器忙，请稍后再尝试！";
            throw new ServiceException(ServiceCode.ERR_UNKNOWN,message);
        }

    }

    @Override
    public void updateInfoById(Long id, UserUpdateDTO userUpdateDTO){
        UserStandardVO queryResult = userMapper.getStandardById(id);
        if (queryResult == null) {
            String message = "修改用户信息失败，该用户不存在！";
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        String name = userUpdateDTO.getUsername();
        int countByName = userMapper.countByNameAndNotId(id,name);
        if (countByName > 0){
            String message = "修改用户信息失败，该用户名已被占用！";
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }

        String nickname =  userUpdateDTO.getNickname();
        int countByNickName = userMapper.countByNickNameAndNotId(id,nickname);
        if (countByNickName > 0){
            String message = "修改用户信息失败，该昵称已被占用！";
            throw new ServiceException(ServiceCode.ERR_CONFLICT,message);
        }
        String password = userUpdateDTO.getPassword();
        if (password!=null&&password!=""){
            BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
            String encodedPassword = passwordEncoder.encode(password);
            userUpdateDTO.setPassword(encodedPassword);
        }
        User user = new User();
        BeanUtils.copyProperties(userUpdateDTO,user);
        user.setId(id);
        int rows = userMapper.update(user);
        if (rows != 1){
            String message = "修改用户信息失败，服务器忙，请稍后再尝试！";
            throw new ServiceException(ServiceCode.ERR_UNKNOWN,message);
        }
    }

    @Override
    public List<ProductListItemVO> getProductListById(Long id){
        UserStandardVO queryResult = userMapper.getStandardById(id);
        if (queryResult == null) {
            String message = "获取用户收藏列表失败，该用户不存在！";
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }
        List<ProductListItemVO> list = userMapper.getProductListById(id);
        return list;
    }


}
